package com.itbaima.csmall.stock.webapi.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.itbaima.csmall.commons.exception.CoolSharkServiceException;
import com.itbaima.csmall.commons.pojo.stock.dto.StockReduceCountDTO;
import com.itbaima.csmall.commons.restful.JsonResult;
import com.itbaima.csmall.commons.restful.ResponseCode;
import com.itbaima.csmall.stock.service.StockService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * <p>库存控制器类</p>
 *
 * @author Chen
 * @since 2023/2/20 14:50:50
 */
@RestController
@RequestMapping("/base/stock")
@Api(tags = "库存模块")
public class StockController {

    @Autowired
    private StockService stockService;

    @GetMapping("/reduce/count")
    @ApiOperation("商品库存减少")
    @SentinelResource(value = "减少库存数", blockHandler = "blockError", fallback = "fallbackError")
    public JsonResult<Void> reduceCommodityCount(StockReduceCountDTO stockReduceCountDTO) {
        stockService.reduceCommodityCount(stockReduceCountDTO);
        if (Math.random() < 0.5) {
            throw new CoolSharkServiceException(ResponseCode.INTERNAL_SERVER_ERROR, "随机异常");
        }
        return JsonResult.ok("商品减少库存完成!");
    }

    /**
     * <p>Sentinel自定义限流方法</p>
     * <ul>
     *     <li>访问修饰符必须是public</li>
     *     <li>返回值类型必须和控制器方法一致</li>
     *     <li>方法名必须是@SentinelResource注解定义的方法名对应</li>
     *     <li>方法的参数和控制器方法参数一致，然后在添加一个参数BlockException表示限流异常</li>
     * </ul>
     */
    public JsonResult<Void> blockError(StockReduceCountDTO stockReduceCountDTO, BlockException blockException) {
        // 此方法运行表示当前请求被限流，给出响应提示当前用户被限流
        return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR, "服务器忙，请稍后再试！");
    }

    public JsonResult<Void> fallbackError(StockReduceCountDTO stockReduceCountDTO, Throwable throwable) {
        // throwable.printStackTrace();
        return JsonResult.failed(ResponseCode.INTERNAL_SERVER_ERROR, "方法异常，服务降级！");
    }

}
